home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
ab20
/
ab20_archive
/
utilities
/
emulators
/
apple2emul.lzh
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-18
|
4KB
|
251 lines
/*
* a2, an Apple II emulator in C
* (c) Copyright 1990 by Rich Skrenta
*
* Command line interface written by Tom Markson
*
* Distribution agreement:
*
* You may freely copy or redistribute this software, so long
* as there is no profit made from its use, sale, trade or
* reproduction. You may not change this copyright notice,
* and it must be included prominently in any copy made.
*
* Send emulator related mail to: skrenta@blekko.commodore.com
* skrenta@blekko.uucp
*/
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include "a2.h"
int save_flags; /* terminal flags */
char escape_char = '~';
unsigned short Pc;
unsigned char Sp = 0xFF; /* stack pointer */
unsigned int A = 0; /* accumulator */
unsigned char X = 0; /* X register */
unsigned char Y = 0; /* Y register */
unsigned int N = 0; /* 7 - sign */
unsigned int V = 0; /* 6 - Overflow */
/* 5 - Unused */
unsigned int B = 1; /* 4 - Break */
unsigned int D = 0; /* 3 - Decimal */
unsigned int I = 0; /* 2 - Interrupt */
unsigned int NZ = 1; /* 1 - Zero */
unsigned int C = 0; /* 0 - Carry */
int term_lines, term_cols;
int running = TRUE;
int tracing = FALSE;
int disk[] = {-1, -1};
int write_prot[2];
int drive = 0;
main(argc, argv)
int argc;
char **argv;
{
int c;
int errflag = 0;
char *f8rom, *d0rom;
int cli_first = FALSE;
safety_check();
f8rom = "AUTOSTART.ROM";
d0rom = "APPLESOFT.ROM";
while ((c = getopt(argc, argv, "cim")) != -1) {
switch (c) {
case 'c':
cli_first = TRUE;
break;
case 'i':
d0rom = "INTEGER.ROM";
break;
case 'm':
f8rom = "MONITOR.ROM";
break;
case '?':
default:
errflag++;
}
}
if (errflag) {
fprintf(stderr, "usage: %s\n", argv[0]);
fprintf(stderr, "\t-m\tLoad MONITOR.ROM instead of AUTOSTART.ROM at $F800\n");
fprintf(stderr, "\t-i\tLoad INTEGER.ROM instead of APPLESOFT.ROM at $D000\n");
fprintf(stderr, "\t-c\tEnter command mode before executing any instructions\n");
exit(1);
}
printf("a2 -- Apple II emulator. Escape character is %c\n",
escape_char);
if (!bload(f8rom, 0xF800))
exit(1);
bload(d0rom, 0xD000);
bload("DISK.PROM", 0xC600);
if (!InitScreen())
exit(1);
ScreenSize(&term_lines, &term_cols);
memory_setup();
set_special_jumps();
Pc = join(mem[0xFFFC], mem[0xFFFD]);
if (cli_first)
cli();
else
ClearScreen();
while (1) {
set_term();
run();
cli();
}
}
restore_term() {
/* SetNormal(); /* Turn off inverse video */
Raw(FALSE);
fcntl(0, F_SETFL, save_flags);
signal(SIGINT, SIG_DFL);
}
set_term() {
int catch_intr();
int cleanup();
signal(SIGINT, catch_intr);
signal(SIGQUIT, cleanup);
signal(SIGTERM, cleanup);
save_flags = fcntl(0, F_GETFL, 0);
Raw(TRUE);
}
cleanup() {
restore_term();
exit(0);
}
catch_intr() {
signal(SIGINT, catch_intr);
running = FALSE;
tracing = FALSE;
}
bload(fnam, addr)
char *fnam;
unsigned short addr;
{
int fd;
long len;
fd = open(fnam, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "can't open %s: ", fnam);
perror("");
return(FALSE);
}
len = 65536 - addr;
if (len == 65536) { /* stupid $%!*&#~ 16 bit systems */
if (read(fd, &mem[addr], 4096) < 0) {
fprintf(stderr, "bad read of %s: ", fnam);
perror("");
return(FALSE);
}
addr += 4096;
len -= 4096;
}
if (read(fd, &mem[addr], len) < 0) {
fprintf(stderr, "bad read of %s: ", fnam);
perror("");
return(FALSE);
}
close(fd);
return(TRUE);
}
bsave(fnam, addr, size)
char *fnam;
unsigned short addr,size;
{
int fd;
unsigned sizel;
int x;
sizel=size;
if (sizel==0) sizel=65535;
fd=open(fnam,O_WRONLY|O_CREAT,0644);
if (fd < 0) {
printf("can't open %s: ", fnam);
perror("");
return;
}
x=write(fd,&mem[addr],sizel);
if (size == 0)
x=write(fd,&mem[65535],1);
if (x==-1) perror("write");
close(fd);
}
/*
* I make certain assumptions about rollover so that I can do
* things like X++ and know that if X is 0xFF it will rollover
* to 0x00. If I didn't know this I'd have to do X = (X+1) & 0xFF
* If your machine assert fails on the code below you'll have to
* rewrite the code that depends on rollover
*/
safety_check() {
unsigned char c;
unsigned short s;
c = 0xFF;
assert(++c == 0x00);
assert(--c == 0xFF);
s = 0xFFFF;
assert(++s == 0x0000);
assert(--s == 0xFFFF);
}
asfail(file, line, cond)
char *file;
int line;
char *cond;
{
fprintf(stderr, "assertion failure: %s (%d): %s\n", file, line, cond);
restore_term();
abort();
exit(1);
}